#include "iccinfo.h"
#include "func/lanefunction.h"
#include <QtEndian>

IccInfo::IccInfo(QObject *parent) :
    QObject(parent)
{
    memset(&this->m_rawIccFile0015, 0, sizeof this->m_rawIccFile0015);
    memset(&this->m_rawIccXinlian0015, 0, sizeof this->m_rawIccXinlian0015);
    memset(&this->m_xinlianTermNo, 0, sizeof this->m_xinlianTermNo);
    this->m_isXinlianCard=false;
    this->m_nGbBalance=0;
    this->m_nXinlianBalance=0;
}

QString IccInfo::toString() const
{
    QString rlt;
    char szBuf[64];
    rlt.append("卡号|");
    rlt.append(QByteArray((char *)m_rawIccXinlian0015.cardNo, 8).toHex());
    rlt.append("|卡类型|");
    szBuf[0]=m_rawIccXinlian0015.cardType;
    szBuf[1]=m_rawIccXinlian0015.subType;
    rlt.append(QByteArray(szBuf, 2).toHex());
    rlt.append("|卡片应用范围|");
    rlt.append(QByteArray((char *)m_rawIccXinlian0015.scope, 2).toHex());
    rlt.append("|交易时间|");
    rlt.append(m_deductTime.toString("yyyyMMddhhmmss"));
    rlt.append("|交易前余额|");
    quint32 balance=qToBigEndian(m_rawIccInitForPurchaseRlt.balanceBeforeInBigEndian);
    double f = balance;
    rlt.append(QString::number(f/100, 'f', 2));
    rlt.append("|交易金额|");
    f = this->m_nMoneyToDeduct;
    rlt.append(QString::number(f/100, 'f', 2));
    rlt.append("|折扣率|");
    f = 0;
    rlt.append(QString::number(f/100, 'f', 2));
    rlt.append("|PSAM卡号|");
    rlt.append(QByteArray((char *)m_xinlianPsamId, 10).toHex());
    rlt.append("|TAC码|");
    rlt.append(QByteArray((char *)m_rawIccTacRlt.tac, 4).toHex().toUpper());
    rlt.append("|终端批次号|");
    rlt.append("?");
    rlt.append("|终端流水号|");
    rlt.append("?");
    rlt.append("|卡片计数器|");
    rlt.append(QString::number(qToBigEndian(m_rawIccInitForPurchaseRlt.transNoInBigEndian)));
    rlt.append("|交易类型标识|");
    rlt.append("09");
    rlt.append("|终端机编号|");
    rlt.append(QByteArray((char *)m_xinlianTermNo, 6).toHex().toUpper());
    rlt.append("|终端交易序列号|");
    rlt.append(QString::number(qToBigEndian(m_rawIccMac1Rlt.termTransNoInBigEndian)));
    return rlt;
}

bool IccInfo::setIcc0015(const quint8 *icc0015, quint8 sizeOfIcc0015)
{
    if (sizeOfIcc0015!=DF01_0015_SIZE)
    {
        logger()->info(tr("Invalid sizeOfIcc0015: [%1]").arg(sizeOfIcc0015));
        return false;
    }
    memcpy(&this->m_rawIccFile0015, icc0015, sizeOfIcc0015);
    // 清空原有信联卡信息
    memset(&this->m_rawIccXinlian0015, 0, sizeof this->m_rawIccXinlian0015);
    this->m_nGbBalance=0;
    this->m_nXinlianBalance=0;
    return true;
}

bool IccInfo::setIcc0015(const QString &icc0015)
{
    if (icc0015.length()!=IccInfo::DF01_0015_SIZE*2)
    {
        return false;
    }
    quint8 raw0015[IccInfo::DF01_0015_SIZE];
    if (!hex2Raw(raw0015, icc0015.toStdString().c_str(), icc0015.length()))
    {
        return false;
    }
    return this->setIcc0015(raw0015, icc0015.length()/2);
}

bool IccInfo::setGbBalance(const quint8 *rawBalance, quint8 sizeOfBalance)
{
    if (sizeOfBalance!=DF01_BALANCE_SIZE)
    {
        logger()->info(tr("Invalid sizeOfBalance: [%1]").arg(sizeOfBalance));
        return false;
    }

    quint32 nRawBalance;
    memcpy(&nRawBalance, rawBalance, 4);
    this->m_nGbBalance=qFromBigEndian(nRawBalance);
    return true;
}

bool IccInfo::setXinlianBaseInfo(const quint8 *xinlian0015, quint8 sizeOfXinlian0015)
{
    if (sizeOfXinlian0015!=DF02_0015_SIZE)
    {
        logger()->info(tr("Invalid sizeOfXinlian0015: [%1]").arg(sizeOfXinlian0015));
        return false;
    }
    RawIccXinlian0015 rawXinlian0015;
    memcpy(&rawXinlian0015, xinlian0015, sizeOfXinlian0015);
    QDate d1, d2;
    if (!bcd2date(&d1, rawXinlian0015.startTime))
    {
        logger()->info(tr("Invalid startTime"));
        return false;
    }
    if (!bcd2date(&d2, rawXinlian0015.expireTime))
    {
        logger()->info(tr("Invalid expireTime"));
        return false;
    }
    this->m_startTime=d1;
    this->m_expireTime=d2;
    memcpy(&this->m_rawIccXinlian0015, &rawXinlian0015, sizeof rawXinlian0015);
    return true;
}

bool IccInfo::setXinlianBaseInfo(const QString &xinlian0015)
{
    if (xinlian0015.length()!=DF02_0015_SIZE*2)
    {
        return false;
    }
    quint8 rawXinlian0015[DF02_0015_SIZE];
    if (!hex2Raw(rawXinlian0015, xinlian0015.toStdString().c_str(), xinlian0015.length()))
    {
        return false;
    }
    return setXinlianBaseInfo(rawXinlian0015, xinlian0015.length()/2);
}

bool IccInfo::isDateValid()
{
    QDate current=QDate::currentDate();
    return (current>=this->m_startTime) &&
           (current<=this->m_expireTime);
}

QString IccInfo::getGBNetworkNo() const
{
    char szNetworkNo[8];
    raw2HexStr(szNetworkNo, this->m_rawIccFile0015.cardNetwork,
               sizeof this->m_rawIccFile0015.cardNetwork);
    return szNetworkNo;
}

QString IccInfo::getGBCardNo() const
{
    char szCardNo[20];
    raw2HexStr(szCardNo, this->m_rawIccFile0015.cardNo,
               sizeof this->m_rawIccFile0015.cardNo);
    return szCardNo;
}

QString IccInfo::getGBCardNoWithNetworkNo() const
{
    return this->getGBNetworkNo()+this->getGBCardNo();
}

QString IccInfo::getVehicleLicencePlateNumber() const
{
    // 车牌转换为UTF-8
    QByteArray ba((char *)m_rawIccFile0015.vehicleLicencePlateNumber, sizeof m_rawIccFile0015.vehicleLicencePlateNumber);
    // 正常车牌以\x00结束
    ba.replace('\x00', ' ');
    ba.replace('\xFF', ' ');
    return QTextCodec::codecForName("GB2312")->toUnicode(ba).trimmed();
}

int IccInfo::getVehicleLicencePlateColor() const
{
    return m_rawIccFile0015.vehicleLicencePlateColor;
}

QString IccInfo::getXinlianCardNo() const
{
    char szCardNo[20];
    raw2HexStr(szCardNo, this->m_rawIccXinlian0015.cardNo,
               sizeof this->m_rawIccXinlian0015.cardNo);
    return szCardNo;
}
